package system

import (
	consts2 "MoSkeleton/config/consts"
	"MoSkeleton/framework/core/dto/response"
	"MoSkeleton/framework/core/models"
	"MoSkeleton/framework/utils"
	"MoSkeleton/models/system"
	"MoSkeleton/services/base"
	system3 "MoSkeleton/web/pogos/request/system"
	system2 "MoSkeleton/web/pogos/response/system"
	"bytes"
	"gorm.io/gorm"
	"strconv"
)

type SysDictDataService struct {
}

/*
	 select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark
			from sys_dict_data

where status = '0' and dict_type = #{dictType} order by dict_sort asc
*/
func (d *SysDictDataService) GetDataListByDictType(dictType string) (*[]system2.SysDictDataItemResp, error) {
	dictData := system.SysDictData{}
	dictData.Status = "0"
	dictData.DictType = dictType
	dataItemResps := make([]system2.SysDictDataItemResp, 0)
	if err := base.BaseDb.Model(&dictData).Where(&dictData).Find(&dataItemResps).Error; err != nil {
		return nil, err
	}
	return &dataItemResps, nil
}

func (d *SysDictDataService) GetDictDataById(id uint64) (*system2.SysDictDataItemResp, error) {
	itemResp := system2.SysDictDataItemResp{}
	if err := base.BaseDb.Model(&system.SysDictData{}).Where("id = ?", id).First(&itemResp).Error; err != nil {
		return nil, err
	}
	return &itemResp, nil
}

/*
select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark

	from sys_dict_data
	<where>
	    <if test="dictType != null and dictType != ''">
			AND dict_type = #{dictType}
		</if>
		<if test="dictLabel != null and dictLabel != ''">
			AND dict_label like concat('%', #{dictLabel}, '%')
		</if>
		<if test="status != null and status != ''">
			AND status = #{status}
		</if>
	</where>
	order by dict_sort asc
*/
func (d *SysDictDataService) GetDictDataPage(dictDataReq *system3.DictDataPageReq) (*response.PageResult, error) {
	db := d.getDictDataListVo(dictDataReq)
	result := make([]system2.SysDictDataItemResp, 0)
	var total int64
	if err := db.Count(&total).Offset(dictDataReq.Offset()).Limit(dictDataReq.Limit()).Find(&result).Error; err != nil {
		return nil, err
	}
	pageResult := response.NewFromPageInfoAndData(&dictDataReq.PageInfo, &result, total)
	return pageResult, nil
}

func (d *SysDictDataService) ExportDictData(dictDataReq *system3.DictDataPageReq) (*bytes.Buffer, error) {
	db := d.getDictDataListVo(dictDataReq)
	itemsResp := make([]system2.SysDictDataItemResp, 0)
	if err := db.Find(&itemsResp).Error; err != nil {
		return nil, err
	}
	titles := []string{"字典编号", "字典排序", "字典标签", "字典键值", "字典类型", "是否默认", "状态"}
	exportFile := utils.NewExportExcelFile()

	return exportFile.Export(consts2.Excel_Sheet_DictData, &titles, func(row, col int, colTitle string) (value any, ok bool, err error) {
		if len(itemsResp) <= row {
			return "", false, nil
		}
		itemResp := itemsResp[row]
		switch col {
		case 0:
			return "'" + strconv.FormatUint(itemResp.ID, 10), true, nil
		case 1:
			return itemResp.DictSort, true, nil
		case 2:
			return itemResp.DictLabel, true, nil
		case 3:
			return itemResp.DictValue, true, nil
		case 4:
			return itemResp.DictType, true, nil
		case 5:
			if itemResp.IsDefault == consts2.U_YES {
				return "是", true, nil
			} else {
				return "否", true, nil
			}
		case 6:
			if itemResp.Status == consts2.U_NORMAL {
				return "正常", true, nil
			} else {
				return "停用", true, nil
			}
		}
		return "", false, nil
	})
}

func (d *SysDictDataService) AddDictData(addReq *system3.DictDataAddReq) (bool, error) {
	dictData := system.SysDictData{}
	if err := utils.CopyStruct(&dictData, addReq); err != nil {
		return false, err
	}
	result := base.BaseDb.Save(&dictData)
	return result.RowsAffected > 0, result.Error
}

func (d *SysDictDataService) UpdateDateTypeById(updateReq *system3.SysDictDataUpdateReq) (ok bool, err error) {
	dictData := system.SysDictData{}

	if err := utils.CopyStruct(&dictData, updateReq); err != nil {
		return false, err
	}
	return true, dictData.UpdateDictDataById(nil)
}

func (d *SysDictDataService) DeleteById(id uint64) (bool, error) {
	dictData := system.SysDictData{MoModel: models.MoModel{ID: id}}
	result := base.BaseDb.Model(&dictData).Delete(&dictData)
	return result.RowsAffected > 0, result.Error
}

func (d *SysDictDataService) getDictDataListVo(dictDataReq *system3.DictDataPageReq) *gorm.DB {
	db := base.BaseDb.Model(&system.SysDictData{})
	if dictDataReq.DictType != "" {
		db.Where("dict_type = ?", dictDataReq.DictType)
	}
	if dictDataReq.DictLabel != "" {
		db.Where("dict_label like ?", "%"+dictDataReq.DictLabel+"%")
	}
	if dictDataReq.Status != "" {
		db.Where("status = ?", dictDataReq.Status)
	}
	db.Order("dict_sort asc ")
	return db
}
